package J1939;


import kstech.com.wifitest.listener.BatteryListener;

enum VARTYPE {
	BYTE, WORD, DWORD, SHORT, INT, FLOAT
}

/**
 * ���ݱ����࣬���������ļ��еĵ�ÿ��<DSItem>��ǲ���һ�������ʵ������
 */
public class J1939_DataVar_ts {

	public BatteryListener batteryListener;

	/**
	 * ���ݱ���ֵ���ͣ� ��Ӧ�����ļ���
	 * <DSItem>��ǵ�"DataType"����ֵ��BYTE��WORD��DWORD��CHAR��SHORT��INT��FLOAT��
	 */
	public VARTYPE bDataType;

	/**
	 * �����ͣ��������������ݱ�����ֵ����Ӧ�����ļ��� <DSItem>��ǵ�"Value"����ֵ
	 * ��long�������Եĵ�ַ�ռ�ɴ��BYTE��WORD��SHORT��INT��DWORD��FLOAT���͵�ֵ
	 */
	private long unValue;

	/**
	 * �������ȣ���Ӧ <DSItem>��ǵġ�Rows"����ֵ Ϊ0��ʾ������Ϊ�����ͱ���������ֵΪunValue;
	 * ��0��ʾ������Ϊ����������ֵΪvValue
	 */
	public short wRows;

	/**
	 * ������������Ӧ <DSItem>��ǵġ�IndexBy"����ֵ��������ֵΪĳ�������� ��������ָ������ֵ��Ϊ���ʱ�����Ԫ�ص�����
	 */
	private short wRowIndexBy;

	/**
	 * �������͵����ݱ���ֵ����Ӧ <DSItem>��ǵ�����<Data>�ӱ�ǵġ�Value"����ֵ ����Ԫ�ص�ֵ������bDataTypeȷ��
	 */
	private Object vValue;

	/**
	 * ���ݱ�����ID, ��Ӧ�����ļ��е� <DSItem>��ǵ�"ID"����ֵ
	 */
	public short wDataID;

	/**
	 * ���ݱ������������ַ�����Դ���е���������Ӧ�����ļ��� <DSItem>��ǵ�"RemarkID"����ֵ
	 */
	public short wRemarkStrID;

	/**
	 * ���ݱ�������(��ƣ�����Ӧ�����ļ��� <DSItem>��ǵ�"Name"����ֵ�������ļ���ͨ�����������������ݱ���
	 */
	public String sName;

	/**
	 * ���ݱ���ֵ�ĵ�λ�� ��Ӧ�����ļ��� <DSItem>��ǵ�"Unit"����ֵ
	 */
	public String sUnit;

	/**
	 * ���ݱ���ֵ��ʾ���ȣ�С�������ʾλ��������Ӧ�����ļ��� <DSItem>��ǵ�"DecLen"����ֵ
	 */
	public byte bDataDec;

	/**
	 * ������������Ӧ<DSItem>��ǵġ�LinkTo"����ֵ��������ֵΪĳ�������� ��������ָ�����Ǳ������������ӵĴ�������
	 */
	public short wLinkTo;

	/**
	 * ����������SP���á� ��ĳSP���õ�Refָ�򱾱���ʱ���Ը�SP���������ñ�����
	 */
	public J1939_SPCfg_ts pSPCfg;



	public boolean isFloatType() {
		return bDataType.equals(VARTYPE.FLOAT);
	}

	public byte getDataType() {
		return Byte.valueOf(bDataType.ordinal() + "");
	}

	public void setName(String sName) {
		this.sName = sName;
	}

	public void setUnit(String sUnit) {
		this.sUnit = sUnit;
	}

	public void setDecLen(String sDataDec) {
		if (sDataDec != null) {
			this.bDataDec = Byte.valueOf(sDataDec);
		}
	}

	public void setLinkTo(short wLinkTo) {
		this.wLinkTo = wLinkTo;
	}

	public void setRemarkID(short remarkID) {
		this.wRemarkStrID = remarkID;
	}

	public void setDataID(String dataID) {
		this.wDataID = Short.valueOf(dataID);
	}

	/**
	 * �������ݱ������� ���õ�����ֵ����Ϊ�������͵����ݱ�����Ԫ������
	 *
	 * @param wDataVarIndex
	 *            : ��������
	 * @return ����������ָ������ĵ�ǰֵ
	 */
	public static short GetRowIndexByDataVarIndex(short wDataVarIndex) {
		return (short) (J1939_Context.j1939_DataVarCfg[wDataVarIndex]
				.getValue());
	}

	/**
	 * �����ͱ������캯��
	 *
	 * @param dataType
	 *            : ��������������
	 * @param value
	 *            : ����ֵ
	 */
	public J1939_DataVar_ts(String dataType, String value) {
		VARTYPE bDataType = VARTYPE.valueOf(dataType);
		this.bDataType = bDataType; //
		if (value == null || value.trim().length() == 0) {
			// TODO:��Ҫ����������
		} else if (bDataType == VARTYPE.FLOAT) {
			this.unValue = Float.floatToIntBits(Float.valueOf(value));
		} else {
			int iValue = Integer.valueOf(value);
			if (bDataType.equals(VARTYPE.SHORT)
					|| bDataType.equals(VARTYPE.INT)) {

			} else if (bDataType == VARTYPE.BYTE) {
				this.unValue = iValue & 0x000000FF;
			} else if (bDataType == VARTYPE.WORD) {
				this.unValue = iValue & 0x0000FFFF;
			} else if (bDataType == VARTYPE.DWORD) {
				this.unValue = ((long) iValue) & 0xFFFFFFFFl;
			} else {
				this.unValue = (long) iValue; // Short, int����
			}
		}
		this.wRows = 0; //
		this.wRowIndexBy = (short) 0xFFFF; // ��������Ԫ������
		this.wLinkTo = (short) 0xFFFF; // ��ʼ��Ϊ�� LinkTo
	}

	/**
	 * �������������ֽڡ��֡�˫�����ͣ��������캯��
	 *
	 * @param bDataType
	 *            : ��������������
	 * @param iValue
	 *            : ����ֵ��WORD, DWORD����ֵҪת��Ϊint����ֵ����ʵ����������
	 */
	public J1939_DataVar_ts(VARTYPE bDataType, int iValue) {
		super();
		if (bDataType != VARTYPE.FLOAT) {
			if (bDataType == VARTYPE.BYTE) {
				this.unValue = iValue & 0x000000FF;
			} else if (bDataType == VARTYPE.WORD) {
				this.unValue = iValue & 0x0000FFFF;
			} else if (bDataType == VARTYPE.DWORD) {
				this.unValue = ((long) iValue) & 0xFFFFFFFFl;
			} else {
				this.unValue = (long) iValue; // Short, int����
			}
			this.bDataType = bDataType; //
			this.wRows = 0; //
			this.wRowIndexBy = (short) 0xFFFF; // ��������Ԫ������
			this.wLinkTo = (short) 0xFFFF; // ��ʼ��Ϊ�� LinkTo
		} else { //
			// ָ��������ֵ���Ͳ�ƥ��
		}
	}

	/**
	 * �������ͱ������캯��
	 *
	 * @param bDataType
	 *            : ����Ԫ�ص���������
	 * @param wRows
	 *            : ��������
	 * @param wRows
	 *            : ��������
	 * @param wRowIndexBy
	 *            : ��������ָʾ�����������ɸ�����������ֵָʾ����Ԫ��λ��
	 * @param objValue
	 *            : �������飬�����ͱ�����bDataTypeƥ�䡣��� objValue=NULL,
	 *            ���Զ���ָ�����ͷ���ָ�����ȵ����鲢��ʼ��Ϊ0
	 * */
	public J1939_DataVar_ts(String dataType, short wRows, short wRowIndexBy,
							Object[] objValue) {
		VARTYPE bDataType = VARTYPE.valueOf(dataType);
		if (objValue != null) {
//			String sObjType = objValue.getClass().getName();
			String sObjType = dataType;
			if ((sObjType.startsWith("B") && (bDataType == VARTYPE.BYTE))
					|| (sObjType.startsWith("I") && ((bDataType == VARTYPE.INT) || (bDataType == VARTYPE.DWORD)))
					|| (sObjType.startsWith("S") && ((bDataType == VARTYPE.SHORT) || (bDataType == VARTYPE.WORD)))
					|| (sObjType.startsWith("F") && (bDataType == VARTYPE.FLOAT))) {
				if ((objValue).length == (int) wRows) {
					this.vValue = objValue;
				} else {
					// �������Ȳ�ƥ��
				}
			} else {
				// ����Ԫ�����Ͳ�ƥ��
			}
		} else {
			// δָ���������飬��ָ�����ͺͳ�������
			if (bDataType == VARTYPE.BYTE) {
				this.vValue = new byte[(int) wRows];
			} else if ((bDataType == VARTYPE.SHORT)
					|| (bDataType == VARTYPE.WORD)) {
				this.vValue = new short[(int) wRows];
			} else if ((bDataType == VARTYPE.INT)
					|| (bDataType == VARTYPE.DWORD)) {
				this.vValue = new int[(int) wRows];
			} else if (bDataType == VARTYPE.FLOAT) {
				this.vValue = new float[(int) wRows];
			} else {
				// ��Ч����
			}

		}

		this.bDataType = bDataType; //
		this.wRows = wRows; //
		this.wRowIndexBy = wRowIndexBy; // ��ʼ��Ϊδ��������
		this.wLinkTo = (short) 0xFFFF; // ��ʼ��Ϊ�� LinkTo

	}

	/**
	 * ��ȡ�������͵ı���ֵ
	 *
	 * @param ��
	 * @return �������͵ı���ֵ
	 */
	public float getFloatValue() {

		short wRowIndex;

		if (bDataType == VARTYPE.FLOAT) {
			if (wRows == 0) {
				return Float.intBitsToFloat((int) unValue);
			} else {
				if (wRowIndexBy != 0xFFFF && vValue != null) {
					wRowIndex = GetRowIndexByDataVarIndex(wRowIndexBy);
					if (wRowIndex >= 0 && wRowIndex < wRows) {
						return ((float[]) vValue)[wRowIndex];
					}
				}
			}
		}

		// ���ܻ�ȡ���������ֵ
		return (11111.11f);

	}

	/**
	 * ���ø������͵ı���ֵ
	 *
	 * @param
	 * @return
	 */
	public byte setFloatValue(float fValue) {

		short wRowIndex;

		if (bDataType == VARTYPE.FLOAT) {
			if (wRows == 0) {
				this.unValue = Float.floatToIntBits(fValue);
				return (1);
			} else {
				if (wRowIndexBy != 0xFFFF && vValue != null) {
					wRowIndex = GetRowIndexByDataVarIndex(wRowIndexBy);
					if (wRowIndex >= 0 && wRowIndex < wRows) {
						((float[]) vValue)[wRowIndex] = fValue;
						return (1);
					}
				}
			}
		}

		// �������ø������͵ı���ֵ
		return (0);
	}

	/**
	 * ��ȡ�������͵ı���ֵ
	 *
	 * @return �����ͱ���ֵ
	 */
	public long getValue() {

		short wRowIndex;

		if (bDataType != VARTYPE.FLOAT) {
			if (wRows == 0) {
				return (unValue);
			} else {
				if ((wRowIndexBy != 0xFFFF) && (vValue != null)) {
					wRowIndex = GetRowIndexByDataVarIndex(wRowIndexBy);
					if ((wRowIndex >= 0) && (wRowIndex < wRows)) {
						if (bDataType == VARTYPE.BYTE)
							return ((byte[]) vValue)[wRowIndex];
						else if ((bDataType == VARTYPE.SHORT)
								|| (bDataType == VARTYPE.WORD))
							return ((short[]) vValue)[wRowIndex];
						else if ((bDataType == VARTYPE.INT)
								|| (bDataType == VARTYPE.DWORD))
							return ((int[]) vValue)[wRowIndex];
						else {
							// ��Ч����������
						}
					}
				}
			}
		}

		// ���ܻ�ȡ����������ֵ
		return (-1l);

	}

	/**
	 * �����������͵ĵı���ֵ
	 *
	 * @param lValue
	 *            : ��ת��Ϊ�����͵ı���ֵ
	 * @return �Ƿ����óɹ���1 -- ���óɹ� 0 -- ����ʧ��
	 */
	public byte setValue(long lValue) {

		short wRowIndex;

		if (bDataType != VARTYPE.FLOAT) {
			if (wRows == 0) {
				this.unValue = lValue;
				return (1);
			} else {
				if (wRowIndexBy != 0xFFFF && vValue != null) {
					wRowIndex = GetRowIndexByDataVarIndex(wRowIndexBy);
					if ((wRowIndex >= 0) && (wRowIndex < wRows)) {
						if (bDataType == VARTYPE.BYTE)
							((byte[]) vValue)[wRowIndex] = (byte) (lValue & 0xFFl);
						else if ((bDataType == VARTYPE.SHORT)
								|| (bDataType == VARTYPE.WORD))
							((short[]) vValue)[wRowIndex] = (short) (lValue & 0xFFl);
						else if ((bDataType == VARTYPE.INT)
								|| (bDataType == VARTYPE.DWORD))
							((int[]) vValue)[wRowIndex] = (int) (lValue & 0xFFFFFFFFl);
						else {
							// ��Ч����������
						}
					}
				}
			}
		}

		// �������ø������͵ı���ֵ
		return (0);
	}

	/**
	 * ��ȡ����ָ��λ��Ԫ�ص�ֵ������������ת��Ϊ��Ӧ�ĸ�����������
	 *
	 * @param wIdx
	 * @return
	 */
	public float getFloatValueByRow(short wRowIdx) {

		float fRet = 0.0f;

		if (wRows == 0) {
			if (bDataType == VARTYPE.FLOAT) {
				return Float.intBitsToFloat((int) unValue);
			} else if (bDataType == VARTYPE.BYTE) {
				return (float) (unValue & 0xFF);
			} else if (bDataType == VARTYPE.SHORT) {
				return (float) ((short) unValue);
			} else if (bDataType == VARTYPE.WORD) {
				return (float) (unValue & 0xFFFFl);
			} else if (bDataType == VARTYPE.INT) {
				return (float) ((int) (unValue));
			} else if (bDataType == VARTYPE.DWORD) {
				return (float) (unValue & 0xFFFFFFFFl);
			}
		} else {
			if (bDataType == VARTYPE.FLOAT) {
				return (Float)((Object[]) vValue)[wRowIdx];
			} else if (bDataType == VARTYPE.BYTE) {
				return (float) (((byte[]) vValue)[wRowIdx] & 0xFF);
			} else if (bDataType == VARTYPE.SHORT) {
				return (float) (((short[]) vValue)[wRowIdx]);
			} else if (bDataType == VARTYPE.WORD) {
				return (float) (((short[]) vValue)[wRowIdx] & 0xFFFF);
			} else if (bDataType == VARTYPE.INT) {
				return (float) (((int[]) vValue)[wRowIdx]);
			} else if (bDataType == VARTYPE.DWORD) {
				return (float) (((int[]) vValue)[wRowIdx] & 0xFFFFFFFFl);
			}
		}

		return (fRet);
	}

}
